"""
<case: 使用selenium进行自动化抢票>
Date: 2024/10/25
Author: 玮玮不吃sakana
"""

from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import datetime
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver import Keys

# 导入其中的webdriver来驱动浏览器
url = "https://kyfw.12306.cn/otn/view/index.html"
login_url = 'https://kyfw.12306.cn/otn/resources/login.html'
order_url = 'https://kyfw.12306.cn/otn/confirmPassenger/initDc'
start_city = input("出发城市:")
arrive_city = input('到达城市:')
train_num = input("车次号：")
leave_month = int(input("出发月份："))
leave_day = int(input("出发日："))
time_to_order = int(input("是否开启定时抢票,(0关1开)"))
if time_to_order:
    target_hour = int(input("开启定时器的目标小时"))
    target_minute = int(input("开启定时器的目标分钟"))
now_month = datetime.date.today().month
print("Go Go Go！！！！")


def begin_to_grap():
    # 在地址栏输入网址
    driver.get(login_url)
    driver.maximize_window()  # 将浏览器窗口最大化
    driver.find_element(By.XPATH, '//*[@id="toolbar_Div"]/div[2]/div[2]/ul/li[2]/a').click()
    WebDriverWait(driver, 1000).until(EC.url_to_be(url))
    time.sleep(1.1)
    # 输入出发城市
    driver.find_element(By.XPATH, '//*[@id="J-index"]/a').click()
    driver.find_element(By.XPATH, '//input[@id="fromStationText"]').click()
    time.sleep(3)
    driver.find_element(By.XPATH, '//input[@id="fromStationText"]').send_keys(start_city)
    driver.find_element(By.ID, "fromStationText").send_keys(Keys.ENTER)
    # 输入到达城市
    driver.find_element(By.XPATH, '//input[@id="toStationText"]').click()
    time.sleep(1)
    driver.find_element(By.XPATH, '//input[@id="toStationText"]').send_keys(arrive_city)
    driver.find_element(By.ID, "toStationText").send_keys(Keys.ENTER)
    time.sleep(2.1)
    # 输入出发时间
    driver.find_element(By.ID, "train_date").click()
    time.sleep(1)
    if leave_month == now_month:
        xpath_str = f'//*[@id="toolbar_Div"]/div[10]/div[1]/div[2]/div[{leave_day}]'
        WebDriverWait(driver, 10, 0.1).until(EC.element_to_be_clickable((By.XPATH, xpath_str)))
        driver.find_element(By.XPATH, xpath_str).click()
    elif leave_month == now_month + 1:
        xpath_str = f'//*[@id="toolbar_Div"]/div[10]/div[2]/div[2]/div[{leave_day}]'
        WebDriverWait(driver, 10, 0.1).until(EC.element_to_be_clickable((By.XPATH, xpath_str)))
        driver.find_element(By.XPATH, xpath_str).click()
    else:
        print("购票月份无效bro")
    time.sleep(2)
    # 查询
    WebDriverWait(driver, 1000, 0.5).until(EC.element_to_be_clickable((By.XPATH, '//a[@id="search_one"]')))
    driver.find_element(By.XPATH, '//a[@id="search_one"]').click()
    # 切换页面
    driver.switch_to.window(driver.window_handles[-1])


def search_ticket_info(on_off):
    if on_off:
        # 等待票价信息出现
        WebDriverWait(driver, 1000).until(EC.presence_of_element_located((By.XPATH, '//*[@id="queryLeftTable"]/tr')))
        ticket_list = driver.find_elements(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
        # 可实现查询功能
        erdeng_list = []
        for item in ticket_list:
            temp = {}
            ticket = item.text.replace("\n", " ").split(" ")
            print(ticket[0:-2])
            temp["列车号"] = item.find_element(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@dataran)]/td[1]/div/div/div/a').text
            temp['二等'] = item.find_element(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@dataran)]/td[5]').text
            temp["无座"] = item.find_element(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@dataran)]/td[11]').text
            erdeng_list.append(temp)
        for i in range(len(erdeng_list) - 1):
            print(erdeng_list[i])


def search_to_order():
    # 等待票价信息出现
    WebDriverWait(driver, 1000).until(EC.presence_of_element_located((By.XPATH, '//*[@id="queryLeftTable"]/tr')))
    ticket_list = driver.find_elements(By.XPATH, '//tbody[@id="queryLeftTable"]/tr[not(@datatran)]')
    for tr in ticket_list:
        train_number = tr.find_element(By.XPATH, "./td[1]/div/div[1]/div/a").text  # 取出元素tr里的列车号
        if train_num == train_number:
            # 判断是否开启定时器
            if time_to_order:
                regular_time_to_grap_ticket()
            WebDriverWait(driver, 1000, 0.1).until(EC.visibility_of_element_located((By.CLASS_NAME, 'btn72')))
            order = locate_button()
            order.click()
            break


def locate_button():
    return driver.find_element(By.CLASS_NAME, 'btn72')


def regular_time_to_grap_ticket():
    global target_hour
    global target_minute
    # 循环等待直到目标时间
    while True:
        current_hour, current_minute = time.localtime()[3:5]
        if current_hour == target_hour and current_minute == target_minute:
            break
        time.sleep(0.1)  # 休眠0.1秒以避免频繁检查时间
    driver.refresh()


def check_info(last_check):
    WebDriverWait(driver, 10, 0.1).until(EC.element_to_be_clickable((By.XPATH, '//*[@id="normalPassenger_0"]')))
    driver.find_element(By.XPATH, '//*[@id="normalPassenger_0"]').click()
    time.sleep(1)
    if EC.presence_of_element_located((By.XPATH, '//div[@id="dialog_xsertcj"]')):
        driver.find_element(By.ID, 'dialog_xsertcj_ok').click()
        # 提交订单
        driver.find_element(By.ID, 'submitOrder_id').click()
        time.sleep(1)

        try:
            # 等待最多10秒，直到元素可点击
            clickable_element = WebDriverWait(driver, 1, 0.2).until(
                EC.element_to_be_clickable((By.XPATH, '//div[@id="erdeng1"]/ul[2]/li[2]/a'))
            )
            # 元素可点击，执行点击操作
            clickable_element.click()
        except:
            print("系统选座")
            pass
        if last_check:
            # 点击确认订单
            driver.find_element(By.ID, 'qr_submit_id').click()
    else:
        # 提交订单
        driver.find_element(By.ID, 'submitOrder_id').click()
        time.sleep(2)
        if EC.presence_of_element_located((By.XPATH, '//div[@id="erdeng1"]/ul[2]/li[2]/a')):
            driver.find_element(By.XPATH, '//div[@id="erdeng1"]/ul[2]/li[2]/a').click()
        else:
            pass

        if last_check:
            # 点击确认订单
            driver.find_element(By.ID, 'qr_submit_id').click()
    time.sleep(3)


if __name__ == '__main__':
    # 启动Edge浏览器
    driver = webdriver.Edge()
    # 开启浏览器输入出发站到达站及时间并点击查询
    begin_to_grap()
    # 查询车票信息（True为开启，False为关闭）
    search_ticket_info(False)
    # 找到填写的车次并下单
    search_to_order()
    # 用于开启检查是否学生票点击并提交订单 （True为开启最后确认提交，False为关闭最后提交）
    check_info(False)
    driver.quit()
    print(
        "我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买我不买")
